package com.sali.回溯算法;

/**
 * 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中，返回 true ；否则，返回 false 。
 * <p>
 * 单词必须按照字母顺序，通过相邻的单元格内的字母构成，其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
 */
public class LeetCode_79 {

    public static void main(String[] args) {
//        char[][] board = new char[][]{
//                {'A','B','C','E'},
//                {'S','F','C','S'},
//                {'A','D','E','E'}
//        };
//        String word = "ABCCED";

        char[][] board = new char[][]{{'a'}};
        String word = "a";
        boolean exist = exist(board, word);
        System.out.println(exist);
    }


    public static boolean exist(char[][] board, String word) {
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[0].length; j++) {
                boolean[][] visited = new boolean[board.length][board[0].length];
                if (getRes(board, word, visited, i, j, 0)) {
                    return true;
                }
            }
        }
        return false;
    }

    private static boolean getRes(
            char[][] board,
            String word,
            boolean[][] visited,
            int i, int j,
            int index) {
        if (i < 0 || i >= board.length || j < 0 || j >= board[0].length) {
            return false;
        }
        if (visited[i][j]) {
            return false;
        }
        if (board[i][j] != word.charAt(index)) {
            return false;
        }
        if (index == word.length() - 1) {
            return true;
        }

        visited[i][j] = true;

        int[] xDir = new int[]{1, -1, 0, 0};
        int[] yDir = new int[]{0, 0, 1, -1};
        for (int k = 0; k < 4; k++) {
            boolean flag = getRes(board, word, visited, i + xDir[k], j + yDir[k], index + 1);
            if (flag) {
                return true;
            }
        }
        visited[i][j] = false;
        return false;
    }

}
